"use strict";
// ============================================================================================
// 基础类型：布尔类型，数值类型，大数值类型，字符串类型
// --------------------------------------------------------------------------------------------
// boolean
// var flag: boolean = true;
// ============================================================================================
// 函数
// --------------------------------------------------------------------------------------------
// 类型签名/类型注释/类型约束
// 类型签名:在函数中涉及到数据的地方只有形参和返回值，所以在ts函数中的函数就是对形参和饭或者做的类型签名
// 基本使用：相当于把ts中的基础类型和高级类型以及其他类型结合起来使用
// function fn(a:number|string,b:number|string):void{
// }
// --------------------------------------------------------------------------------------------
// 可选参数/默认参数
// 要放在普通参数后面不然会报错，和js的？使用相同
// function fn(a:number|string,b:number,c?:number):void{
// }
// --------------------------------------------------------------------------------------------
// 函数重载
// --------------------------------------------------------------------------------------------
// 索引签名
// 声明的时候无法知道属性名及类型，在使用的时候才知道属性名和类型
// interface IInfo{
//   name:string,
//   age:number,
//   //a是一个变量，代表属性的名称
//   [a : string] : unknown
// }
// var user:IInfo={
//   name:'jay',
//   age:18,
//   sex:'man'
// }
// ============================================================================================
// 类型推断&类型断言&非空断言
// ============================================================================================
// 对象/接口
// 接口:描述对象的行为和状态
// interface IUser {
//   id: number;
//   // 只读
//   readonly name: string;
//   // 可选
//   age?: number;
//   // 索引签名
//   [a: string]: unknown;
//   // 函数类型
//   say(name:string,age:number):void
// }
// const user: IUser = {
//   id: 0,
//   name: "jay",
//   age: 18,
//   sex: "man",
//   say(name,age) {
//   }
// };
// // class
// class Man implements IUser{
//     [a: string]: unknown;
//     id:number = 0
//     age:number = 0
//     sex:string = '未知'
//     name:string ='匿名'
//     say(name: string, age: number): void {
//     }
//     constructor(name:string){
//         this.name=name
//     }
// }
// // class 和interface的异同点
// // 1.都可以作为类型
// // 2.class不仅有类型，还可以有值，interface只有类型
// class Animal{
//     id:number
//     name:string
//     constructor(id:number,name:string){
//         this.id=id
//         this.name=name
//     }
// }
// // 接口继承动物类
// interface M extends Animal{
//     age:number
// }
// const user2:M={
//     id:0,
//     name:'jay',
//     age:18
// }
// ============================================================================================
// 类型别名
// 很多场景下和interface是一样的，但是类型别名使用场景更广泛，他不会生成新的类型
// 但是类型别名的语义性（可读性）不高，所以官方推荐优先使用interface
// type TAge = string | number;
// const age: TAge = 12 + "15 ";
// type TUser = {
//   name: string;
//   age: number;
// };
// const user: TUser = {
//   name: "jay",
//   age: 15,
// };
// interface IUser {
//   name: string;
//   age: number;
// }
// // &
// type a = {
//   name: string;
//   age: number;
// };
// type b = {
//   sex: string;
//   hobby: string;
// };
// type s = a & b;
// const c: s = {
//   name: "jay",
//   age: 15,
//   sex: "man",
//   hobby: "music",
// };
// 类型别名和接口的区别
// 1.接口可以继承和实现，类型别名不行
// 2.接口会创建一个新的类型，类型别名不会
// 3.接口只能定义对象的类型，类型别名还可以定义其他的类型
// ============================================================================================
// 类型守卫
// --------------------------------------------------------------------------------------------
// in
// interface a {
//   name: string;
//   sex: string;
// }
// interface b {
//   name: string;
//   age: number;
// }
// function fn(is: a | b) {
//   if ("name" in is) {
//     return is;
//   }
//   if ("age" in is) {
//     return is;
//   }
// }
// --------------------------------------------------------------------------------------------
// typeof
// interface IInfo {
//   name: string;
//   age: number;
// }
// interface YInfo {
//   sex: string;
//   age: number;
// }
// function fn(agt: string | number): agt is string {
//   return typeof agt === "string";
// }
// --------------------------------------------------------------------------------------------
// //keyof
// interface IUser {
//   namae: string;
//   age: number;
//   sex: string;
//   hobby: string;
// }
// type TUser = keyof IUser;
// const user: TUser = "hobby";
// ============================================================================================
// Class类
// class Father {
//   // 如果类里面的成员属性没有初始值，而是通过实例化的时候传入的，此时需要constructor
//   // 如果类里的成员属性有初始值，可以不用写constructor
//   type: string;
//   constructor(type: string) {
//     this.type = type;
//   }
//   say(): void {
//     console.log(`我是${this.type}`);
//   }
// }
// // Son是Father的子类，也叫派生类，这里Father就是父类、基类、超类
// class Son extends Father {
//   name: string;
//   constructor(name: string, type: string) {
//     // super一定是放在最前面的，前面不允许有任何代码
//     super(type);
//     this.name = name;
//     this.type = type;
//   }
// }
// const f = new Father("父亲");
// f.say();
// const s = new Son("丽丽", "爸爸");
// s.say();
// --------------------------------------------------------------------------------------------
// 类方法重载
// class Cz {
//   Cod(): void;
//   Cod(type: string): void;
//   Cod(type: string[]): void;
//   Cod(type?: string | string[]) {
//     if (typeof type === "string") {
//       return console.log("string");
//     } else if (!type) {
//       return console.log("jkbkddnkjcnsdn");
//     } else {
//       return console.log(type);
//       ;
//     }
//   }
// }
// const c = new Cz();
// c.Cod();
// c.Cod(["123", "231", "321"]);
// c.Cod("你好");
// --------------------------------------------------------------------------------------------
// 类的修饰符
//  class Father {
//     // public 任何地方都可以用，readonly表示只读，无法修改
//     // private 只有该类内部可以通过this使用
//      public readonly type: string
//      private body:boolean =true
//       constructor(type: string) {
//         this.type = type
//       }
//       protected move():void{
//         console.log('我会动');
//       }
//       say(): void {
//         console.log(`我是${this.move()}`)
//       }
//     }
// ============================================================================================
// 工具类型
// --------------------------------------------------------------------------------------------
// Partial<可选>，
// Partial把类型全部变为可选
// 源码：
// type P<IUser> = {
//   [P in keyof IUser]+?: IUser[P];
// };
// 例子：
// interface IUser {
//   name: string;
//   sex: string;
//   age: number;
// }
// const u: Partial<IUser> = {
//   name: "jay",
//   // sex:'man',
//   age: 18,
// };
// --------------------------------------------------------------------------------------------
// Required<必填>
// interface INum {
//   one: number;
//   two: number;
//   three: number;
// }
// const n: Required<INum> = {
//   one: 11,
//   two: 22,
//   three: 33,
// };
// --------------------------------------------------------------------------------------------
// Readonly<只读>
// interface INum{
//   one:number;
//   two:number;
//   three:number,
// }
// const n:Readonly<INum>={
//   one:11,
//   two:22,
//   three:33,
// }
// n.one=26; //无法为one赋值因为它是只读属性
// --------------------------------------------------------------------------------------------
// Record<key，type>对象
// 创建一个新的类型，同时将key中的所有属性的值的类型转换为type
// type a =Record<'x'|'y',number>
// 等同于
// type a = {
//     x: number;
//     y: number;
// }
// --------------------------------------------------------------------------------------------
// Pick<type,key>部分
// interface INum {
//   one: number;
//   two: number;
//   three: number;
// }
// const a: Pick<INum, 'one'|'two'> = {
//   one: 10,
//   two:15,
// };
// --------------------------------------------------------------------------------------------
// Omit<type,key>移除
// interface INum {
//   one: number;
//   two: number;
//   three: number;
// }
// const a: Omit<INum, 'one'|'two'> = {
//  three:33,
// };
// --------------------------------------------------------------------------------------------
// Exclude<Type, ExcludedUnion>排除
// Exclude 通过排除类型中可分配给 ExcludedUnion 的所有联合成员来创建新类型
// --------------------------------------------------------------------------------------------
// Extract<Type, Union>交集
// Extract 是 Exclude 的反面。它通过从可分配给联合的类型中提取所有联合成员来创建新类型
// ============================================================================================
// 命名空间
// 里面的IUser不会和外面的IUser冲突
// namespace demo {
//   // 需要export导出，才可以读取到这里的IUser
//   export interface IUser {
//     name: string;
//     age: number;
//   }
// }
// interface IUser {
//   sex: string;
// }
// // 如果要读取里面的IUser
// const a: demo.IUser = {
//   name: "jay",
//   age: 18,
// };
//     ///三斜杠引入文件
// ============================================================================================
// 声明文件
